package cn.jhz.filesharingsystem.controller;

import java.io.IOException;
import java.io.OutputStream;
import java.util.HashSet;
import java.util.Set;

import javax.imageio.ImageIO;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

import cn.jhz.filesharingsystem.model.Permission;
import cn.jhz.filesharingsystem.model.Role;
import cn.jhz.filesharingsystem.model.User;
import cn.jhz.filesharingsystem.service.UserService;
import cn.jhz.filesharingsystem.util.CaptchaUtil;
import cn.jhz.filesharingsystem.util.SecurityUtil;
import cn.jhz.filesharingsystem.web.AuthMethod;

@Controller
public class LoginController {

	@Autowired
	private UserService userService;

	/**
	 * 这里首页其实是登录页
	 * 
	 * @return
	 */
	@GetMapping("/login")
	private String login(HttpSession session) {
		if (session.getAttribute("loginUser") != null && ((boolean) (session.getAttribute("isadmin")) == true
				|| session.getAttribute("userAllPermRes") != null))
			return "redirect:/main";
		else {
			return "login";
		}
	}

	/**
	 * 获取验证码
	 * 
	 * @param session
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	@GetMapping("/login/checkCode")
	private void CheckCode(HttpSession session, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("image/jpg");
		int width = 100;
		int height = 30;
		// 具体画验证码
		CaptchaUtil captcha = CaptchaUtil.getInstance();
		captcha.set(width, height);
		String cc = captcha.generateCheckcode();
		session.setAttribute("checkCode", cc);
		OutputStream out = response.getOutputStream();
		ImageIO.write(captcha.generateCheckImg(cc), "jpg", out);
	}

	@PostMapping("/login/register")
	private String register(
			@RequestParam(value = "username", required = true) String username,
			@RequestParam(value = "password", required = true) String password,
			@RequestParam(value = "email", required = true) String email,
			@RequestParam(value = "checkCode", required = true) String checkCode, HttpServletResponse resp, HttpSession session) {

		if (!session.getAttribute("checkCode").equals(checkCode))
			throw new RuntimeException("验证码错误");

		User newUser = userService.register(username, password, email);
		ServletContext servletContext = session.getServletContext();

		/* 将新的session放入 */
		servletContext.setAttribute(email, session); 
		session.setAttribute("loginUser", newUser);
		
		SecurityUtil.createCookie(email, resp, -1);
		/* 判断session中是否已有权限 */
		Role role = newUser.getRole(); 
		// 拿到登录成功的用户所有关联的所有角色信息
		boolean isadmin = false; // 是：true，不是：false
		Set<String> userAllpermRes = new HashSet<>(); // 权限标记
		Set<Permission> permissions; // 角色对应权限url

		/* 
		 * 不是超级管理员的情况下,
		 * 我们要把登录成功的用户,
		 * 关联的所有权限标记取出来
		 */
		if (role.getState() == 0 || newUser.getState() == 0) {

			throw new RuntimeException("帐号已被禁用");
		}
		permissions = role.getPermissions();
		for (Permission permission : permissions) {
			userAllpermRes.add(permission.getResource());
		}

		/* 判断完毕后，userAllpermRes：
		 * 包括了登录成功的用户,所拥有的所有权限的标记 
		 */
		session.setAttribute("isadmin", isadmin);
		if (!isadmin) {
			session.setAttribute("userAllPermRes", userAllpermRes);
		}

		return "redirect:/main";
	}

	/**
	 * 提交登陆信息
	 * 
	 * @param email
	 * @param password
	 * @param checkCode
	 * @param token
	 * @param expiredays
	 * @param account
	 * @param ssid
	 * @param resp
	 * @param session
	 * @return
	 */
	@PostMapping("/login")
	public String login(
			@RequestParam(value = "email", required = true) String email,
			@RequestParam(value = "password", required = true) String password,
			@RequestParam(value = "checkCode", required = true) String checkCode,
			@RequestParam(value = "expiredays", required = false) String expiredays,
			@CookieValue(value = "userKey", required = false) String account,
			@CookieValue(value = "ssid", required = false) String ssid, 
			HttpServletResponse resp, HttpSession session) {
	
		/* account 登录账号 */
		/* ssid 标记,通过cookie判断用户是否成功登录 */
		
		ServletContext servletContext = session.getServletContext();

		/* 验证码检查 */
		if (!session.getAttribute("checkCode").equals(checkCode))
			throw new RuntimeException("验证码错误");

		User loginUser = null;
		// 判断用户填写的email和password对不对
		if ((loginUser = userService.login(email, password)) != null) {
			// userService里的login方法，判断邮箱，密码是否正确，否则抛出异常
			expiredays = expiredays == null ? "" : expiredays;
			//expiredays:cookie保存时间
			switch (expiredays) {
			case "7":
				SecurityUtil.createCookie(email, resp, 7 * 24 * 60 * 60);
				break;
			case "30":
				SecurityUtil.createCookie(email, resp, 30 * 24 * 60 * 60);
				break;
			case "100":
				SecurityUtil.createCookie(email, resp, Integer.MAX_VALUE);
				break;
			default:
				SecurityUtil.createCookie(email, resp, -1);
				break;
			}
		}

		/* 将新的session放入 */
		servletContext.setAttribute(email, session); 
		// 若已在异地登陆,让其失效
		session.setAttribute("loginUser", loginUser);
		/* 判断session中是否已有权限 */
		Role role = loginUser.getRole(); 
		// 拿到登录成功的用户所有关联的所有角色信息
		boolean isadmin = false; 
		// 是：true，不是：false
		Set<String> userAllpermRes = new HashSet<>(); 
		// 权限标记
		Set<Permission> permissions; 
		// 角色对应权限url

		/* 判断一下登录成功的用户是不是超级管理员 */
		if ("super".equals(role.getRoleName())) {
			isadmin = true;
			// 标记改true
		} else {
			/* 
			 * 不是超级管理员的情况下,
			 * 我们要把登录成功的用户,
			 * 关联的所有权限标记取出来
			 */
			if (role.getState() == 0 || loginUser.getState() == 0) {
				throw new RuntimeException("帐号已被禁用");
			}
			permissions = role.getPermissions();
			for (Permission permission : permissions) {
				userAllpermRes.add(permission.getResource());
			}
		}

		/* 判断完毕后，userAllpermRes：
		 * 包括了登录成功的用户,所拥有的所有权限的标记
		 */
		session.setAttribute("isadmin", isadmin);
		if (!isadmin) {
			session.setAttribute("userAllPermRes", userAllpermRes);
		}

		return "redirect:/main";
	}

	/**
	 * 注销登陆
	 * 
	 * @param session
	 * @return
	 */
	@AuthMethod
	@GetMapping("/logout")
	private String logout(HttpSession session) {
		User user;
		if ((user = (User) session.getAttribute("loginUser")) != null) {
			String key = user.getEmail();
			Object obj = session.getServletContext().getAttribute(key);
			if (obj != null) {
				if (session.equals(obj)) {
					session.getServletContext().removeAttribute(key);
				}
			}

			session.removeAttribute("token");
			session.removeAttribute("isadmin");
			session.removeAttribute("userAllpermRes");
			session.removeAttribute("loginUser");
			session.invalidate();
		}
		return "login";
	}

}
